package com.example.leetcode.solution;

import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

public class Solution726_2 {
    public static void main(String[] args) {
        String str = "AZaz";
        for (int i = 0; i < str.length(); i++) {
            System.out.println(str.charAt(i) - 0);
        }
//        String s = new Solution726_2().countOfAtoms("(Ww2G4(F(QD(AwD1)3)2D3)3(WD2(C2)2)3(FC)12)5");
//        String s = new Solution726_2().countOfAtoms("H2O");
//        String s = new Solution726_2().countOfAtoms("Nd37At28In40Si48Ti38Ds37Sm(Ho26No38)7(Tm35)24Li14Mo34(Nb7Te45Bk35Sr27Yb11Yb18Rn31)10(Po8)30(Ra)27As7Ir38Mt46BaTi37Np43Sm19Mo46Hs37Ga44ZrAu7Pb44Ca48PaNa15Ds4Ac9(Co2Cd39)5(Lv5Ga36No31Si8)16");
//        String s = new Solution726_2().countOfAtoms("Mg(OH)2");
//        String s = new Solution726_2().countOfAtoms("K4(ON(SO3)2)2");
//        String s = new Solution726_2().countOfAtoms("(NB3)33");
//        String s = new Solution726_2().countOfAtoms("(B2O39He17BeBe49)39");
//        String s = new Solution726_2().countOfAtoms("Be32");
        String s = new Solution726_2().countOfAtoms("(NB3)33");
        System.out.println(s);
    }

    Stack<Integer> stack = new Stack();
    Map<String, Integer> groupMap = new HashMap<>();

    public String countOfAtoms(String formula) {
        StringBuffer str = new StringBuffer();
        for (int i = formula.length() - 1; i >= 0; i--) {
            int times = 1;
            Integer peek = peek();
            char c = formula.charAt(i);
//            String s1 = String.valueOf(c);
            if (c == ')') {
                if (str.length() > 0) {
                    times = Integer.valueOf(str.toString());
                    times *= peek;
                }
                stack.add(times);
                str = new StringBuffer();
            } else if (c == '(') {
                Integer integer = pop();
                if (str.length() > 0) {
                    update(str.toString(), integer);
                }
                str = new StringBuffer();
            } else {
                Integer peek2 = peek();
                if (c >= '0' && c <= '9') {
                    StringBuffer s = pickNum(i - 1, formula);
                    s.append(c);
                    String s2 = pickStr(i - s.length(), formula);
                    if (s2.length() > 0) {
                        update(str.toString(), peek2);
                        update(s2, Integer.valueOf(s.toString()) * peek2);
                        i -= (s.length() + s2.length() - 1);
                        str = new StringBuffer();
                        continue;
                    } else if (s.length() > 1) {
                        i -= (s.length() - 1);
                        str.insert(0, s);
                        continue;
                    }
                } else if (c >= 'A' && c <= 'Z') {
                    str.insert(0, c);
                    update(str.toString(), peek2);
                    str = new StringBuffer();
                    continue;
                }
                str.insert(0, c);
            }
        }
        if (str.length() > 0) {
            Integer peek2 = peek();
            update(str.toString(), peek2);
        }
        StringBuffer stringBuffer = new StringBuffer();
        groupMap.keySet().stream().sorted().forEach(s -> {
            stringBuffer.append(s);
            if (groupMap.get(s) > 1) {
                stringBuffer.append(groupMap.get(s));
            }
        });
        return stringBuffer.toString();
    }

    public void update(String s, int t) {
        if (s.length() <= 0) {
            return;
        }
        Integer integer2 = groupMap.get(s);
        if (integer2 == null) integer2 = 0;
        groupMap.put(s, t + integer2);
    }

    public StringBuffer pickNum(int i, String formula) {
        StringBuffer str = new StringBuffer();
        for (int j = i; j >= 0; j--) {
            char c = formula.charAt(j);
            if (c >= '0' && c <= '9') {
                str.insert(0, c);
            } else {
                return str;
            }
        }
        return str;
    }

    public String pickStr(int i, String formula) {
        StringBuffer str = new StringBuffer();
        for (int j = i; j >= 0; j--) {
            char c = formula.charAt(j);
            if (c >= 'A' && c <= 'Z') {
                str.insert(0, c);
                return str.toString();
            } else if (c >= 'a' && c <= 'z') {
                str.insert(0, c);
            } else {
                return str.toString();
            }
        }
        return "";
    }

    public int peek() {
        Integer peek = 1;
        if (!stack.isEmpty()) {
            peek = stack.peek();
        }
        return peek;
    }

    public int pop() {
        Integer peek = 1;
        if (!stack.isEmpty()) {
            peek = stack.pop();
        }
        return peek;
    }

}
